package jmind.core.concurrent;

import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import jmind.base.util.RandUtil;

import com.google.common.collect.Maps;

public class ReentrantReadWriteLock2 {
    static int threads = 100;
    static final CountDownLatch latch = new CountDownLatch(threads);
    static Map<Integer, Integer> map = Maps.newHashMap();
    static CyclicBarrier barrier = new CyclicBarrier(threads);
    static Lock lock = new ReentrantReadWriteLock().readLock();

    // static Lock lock = new ReentrantLock();

    public static void main(String[] args) {

        for (int i = 0; i < 1000; i++) {
            map.put(i, i + 1000);
        }
        long begin = System.nanoTime();
        for (int i = 0; i < threads; i++) {
            new Thread(new Runner2()).start();
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long time = System.nanoTime() - begin;
        System.out.println("time=" + time);

    }

    static Integer get(int k) {
        try {
            lock.lock();
            Thread.sleep(2);
            return map.get(k);

        } catch (Exception e) {
            return null;
        } finally {
            lock.unlock();
        }

    }

    static class Runner2 implements Runnable {

        @Override
        public void run() {
            int k = RandUtil.nextInt(1000);

            try {

                // barrier的await方法，在所有参与者都已经在此 barrier 上调用 await 方法之前，将一直等待。
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            if (get(k) - k != 1000)
                System.err.println(k);
            latch.countDown();
        }
    }

}
